package cn.xm.pet.service.impl;

import cn.xm.basic.config.BussinessException;
import cn.xm.basic.domain.Point;
import cn.xm.basic.dto.AcceptDto;
import cn.xm.basic.util.BaiduAuditUtils;
import cn.xm.basic.util.CodeGenerateUtils;
import cn.xm.basic.util.DistanceUtil;

import cn.xm.basic.util.PageList;
import cn.xm.order.domain.OrderPetAcquisition;
import cn.xm.order.mapper.OrderPetAcquisitionMapper;
import cn.xm.org.domain.Employee;
import cn.xm.org.domain.Shop;
import cn.xm.org.mapper.EmployeeMapper;
import cn.xm.org.mapper.ShopMapper;
import cn.xm.pet.domain.SearchMasterMsg;
import cn.xm.basic.service.impl.BaseServiceImpl;
import cn.xm.pet.domain.SearchMasterMsgAuditLog;
import cn.xm.pet.mapper.SearchMasterMsgAuditLogMapper;
import cn.xm.pet.mapper.SearchMasterMsgMapper;
import cn.xm.pet.query.SearchMasterMsgQuery;
import cn.xm.pet.service.SearchMasterMsgService;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;


/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xm
 * @since 2022-11-01
 */
@Service
public class SearchMasterMsgServiceImpl extends BaseServiceImpl<SearchMasterMsg> implements SearchMasterMsgService {

    @Autowired
    private SearchMasterMsgMapper searchMasterMsgMapper;
    @Autowired
    private SearchMasterMsgAuditLogMapper searchMasterMsgAuditLogMapper;
    @Autowired
    private ShopMapper shopMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private OrderPetAcquisitionMapper orderPetAcquisitionMapper;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public void publish(SearchMasterMsg searchMasterMsg) {
        // 1.先保存寻主信息，状态待审核
        searchMasterMsgMapper.add(searchMasterMsg);
        // 2.参数校验
        paramVerify(searchMasterMsg);
        // 3.百度ai审核和人工审核
        baiduVerify(searchMasterMsg);
        //3.失败就保存日志
        //4.成功就改状态为通过,寻找shopId,并update寻主信息，
        searchMasterMsg.setState(1);
        // 先查找店铺
        List<Shop> shops = shopMapper.findAll();
        // 获取用户地址经纬度
        Point point = DistanceUtil.getPoint(searchMasterMsg.getAddress());
        // 删选出符合距离条件的shop
        Shop nearestShop = DistanceUtil.getNearestShop(point,shops);
        if (nearestShop != null) {
            searchMasterMsg.setShopId(nearestShop.getId());
        }
        searchMasterMsgMapper.update(searchMasterMsg);
    }

    @Override
    public PageList<SearchMasterMsg> findByParam(SearchMasterMsgQuery searchMasterMsgQuery) {
        Integer totals = searchMasterMsgMapper.findCountByParam(searchMasterMsgQuery);
        if (totals == null || totals == 0) {
            return new PageList<SearchMasterMsg>(0, new ArrayList<SearchMasterMsg>());
        }
        List<SearchMasterMsg> searchMasterMsgs = searchMasterMsgMapper.findByParam(searchMasterMsgQuery);
        return new PageList<>(totals,searchMasterMsgs);
    }

    @Override
    public void reject(SearchMasterMsg searchMasterMsg) {
        if (StringUtils.isBlank(searchMasterMsg.getName())) {
            throw new BussinessException("宠物名不能为空");
        }
        searchMasterMsg.setShopId(null);
        searchMasterMsgMapper.update(searchMasterMsg);
        // 设置日志
        SearchMasterMsgAuditLog searchMasterMsgAuditLog = new SearchMasterMsgAuditLog();
        searchMasterMsgAuditLog.setMsgId(searchMasterMsg.getId());
        searchMasterMsgAuditLog.setState(searchMasterMsg.getState());
        searchMasterMsgAuditLog.setAuditId(searchMasterMsg.getUserId());
        searchMasterMsgAuditLog.setAuditTime(new Date());
        searchMasterMsgAuditLogMapper.add(searchMasterMsgAuditLog);


    }

    @Override
    @Transactional
    public void accept(AcceptDto acceptDto,Long shopId) {
        // 参数校验
        if (acceptDto.getMsgId() == null) {
            throw new BussinessException("寻主消息id不能为空");
        }
        if (shopId == null) {
            throw new BussinessException("接单人店铺不能为空");
        }
        if (acceptDto.getHandler() == null) {
            throw new BussinessException("审核人不能为空");
        }
        if (StringUtils.isBlank(acceptDto.getNote())) {
            throw new BussinessException("备注不能为空");
        }
        // 加同步锁
        SearchMasterMsg searchMasterMsg = searchMasterMsgMapper.findById(acceptDto.getMsgId());
        if (searchMasterMsg == null) {
            throw new BussinessException("没有相应的寻主信息");
        }
        synchronized (searchMasterMsg.getId()) {

            if (searchMasterMsg.getState()==1 && searchMasterMsg.getShopId() == shopId) {
                // 修改寻主消息状态
                searchMasterMsg.setState(2);
                Employee employee = employeeMapper.findById(acceptDto.getHandler());
                searchMasterMsgMapper.update(searchMasterMsg);
                // 生成订单并添加到数据库
                OrderPetAcquisition orderPetAcquisition = initOrderPetAcquisition(acceptDto, shopId, searchMasterMsg, employee);
                orderPetAcquisitionMapper.add(orderPetAcquisition);
                // 设置为10s后如果没有完成，就取消订单
                rocketMQTemplate.asyncSend("pethome_topic",
                        MessageBuilder.withPayload(orderPetAcquisition.getId())
                                .build(), new SendCallback() {
                    @Override
                    public void onSuccess(SendResult sendResult) {
                        System.out.println("成功:" + sendResult);
                    }

                    @Override
                    public void onException(Throwable throwable) {
                        System.out.println("失败:" + throwable.getMessage());
                    }
                }, 3000,3);

            }
        }

    }

    @Override
    public PageList<SearchMasterMsg> finish(SearchMasterMsgQuery searchMasterMsgQuery) {
        searchMasterMsgQuery.setState(3);
        Integer totals = searchMasterMsgMapper.findCountByParam(searchMasterMsgQuery);
        if (totals == null || totals == 0) {
            return new PageList<SearchMasterMsg>(0, new ArrayList<SearchMasterMsg>());
        }
        List<SearchMasterMsg> list = searchMasterMsgMapper.findByParam(searchMasterMsgQuery);
        return new PageList<>(totals,list);
    }


    private OrderPetAcquisition initOrderPetAcquisition(AcceptDto acceptDto, Long shopId, SearchMasterMsg searchMasterMsg, Employee employee) {
        // 生成订单
        OrderPetAcquisition orderPetAcquisition = new OrderPetAcquisition();
        orderPetAcquisition.setOrderSn(CodeGenerateUtils.generateOrderSn(acceptDto.getHandler()));
        orderPetAcquisition.setDigest(acceptDto.getNote());
        orderPetAcquisition.setLastConfirmTime(new Date(System.currentTimeMillis() + 1000*60*60*24*3));
        orderPetAcquisition.setState(0);
        orderPetAcquisition.setPrice(new BigDecimal(searchMasterMsg.getPrice()));
        orderPetAcquisition.setPayType(0);
        orderPetAcquisition.setUserId(searchMasterMsg.getUserId());
        orderPetAcquisition.setShopId(shopId);
        orderPetAcquisition.setAddress(searchMasterMsg.getAddress());
        orderPetAcquisition.setEmpId(employee.getId());
        orderPetAcquisition.setSearchMasterMsgId(searchMasterMsg.getId());
        return orderPetAcquisition;
    }

    public void paramVerify(SearchMasterMsg searchMasterMsg) {
        SearchMasterMsgAuditLog searchMasterMsgAuditLog = new SearchMasterMsgAuditLog();
        if (StringUtils.isBlank(searchMasterMsg.getName()) || StringUtils.isBlank(searchMasterMsg.getAddress())) {
            searchMasterMsgAuditLog.setMsgId(searchMasterMsg.getId());
            searchMasterMsgAuditLog.setNote("宠物名字和地址不能为空");
            searchMasterMsgAuditLogMapper.add(searchMasterMsgAuditLog);
            throw new BussinessException("宠物名字和地址不能为空");
        }
    }

    public void baiduVerify(SearchMasterMsg searchMasterMsg) {
        SearchMasterMsgAuditLog searchMasterMsgAuditLog = new SearchMasterMsgAuditLog();
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(searchMasterMsg.getName()).append(searchMasterMsg.getAddress());
        if (!BaiduAuditUtils.TextCensor(stringBuffer.toString())) {
            searchMasterMsgAuditLog.setMsgId(searchMasterMsg.getId());
            searchMasterMsgAuditLog.setNote("您输入的信息有不合规字符");
            searchMasterMsgAuditLogMapper.add(searchMasterMsgAuditLog);
            throw new BussinessException("您输入的信息有不合规字符");
        }
    }
}
